﻿using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml.Linq;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Xml;

using VDC.COMMON;
using VDC.COMMON.ExceptionHelpers;
using VDC.VONE.BLL;
using VDC.VONE.ENTITIES;
using System.Web.Script.Services;
using System.Web.Script.Serialization;
using VDC.VONE.DAL;
using System.Web.Security;
using System.Collections.Generic;

using VDC.VONE.BLL.ViewModel;
using System.Transactions;
using System.Text;
using System.Text.RegularExpressions;
using VDC.VONE.WSERIVCE;
using System.IO;
using System.Globalization;
using System.Web.Hosting;
using System.Reflection;



namespace VDC.VONE.WSERIVCE{
    public class VOneTiepNhan{
        /// <summary>
        ///     The ma ho so one.
        /// </summary>
        private const string MaHoSoOne = "MHS1";
        /// <summary>
        ///     The aspnetsqlmembershipprovider.
        /// </summary>
        private const string Aspnetsqlmembershipprovider = "AspNetSqlMembershipProvider";

        /// <summary>
        ///     The separator.
        /// </summary>
        private const string Separator = ",";

        /// <summary>
        ///     The number format.
        /// </summary>
        private const string NumberFormat = "N";
        /// <summary>
        ///     The underline.
        /// </summary>
        private const string Underline = "_";
        /// <summary>
        ///     The root path.
        /// </summary>
        private const string RootPath = "~";

        /// <summary>
        ///     The dashes.
        /// </summary>
        private const string Dashes = "-";

        /// <summary>
        ///     The number pattern.
        /// </summary>
        private const string NumberPattern = @"\D+";

        /// <summary>
        ///     The hoanthanh.
        /// </summary>
        private const string Hoanthanh = "HOANTHANH";

        /// <summary>
        ///     The mhs.
        /// </summary>
        private const string Mhs = "MHS";

        /// <summary>
        ///     The profile id.
        /// </summary>
        private int profileId = -1;

        /// <summary>
        ///     The main process
        /// </summary>
        private const string MainProcess = "Xử lý chính";

        /// <summary>
        ///     The file upload path hoso.
        /// </summary>
        private const string FileUploadPathHoso = "FileUploadPathHoso";

      

        /// <summary>
        ///     The dangxuly.
        /// </summary>
        private const string Dangxuly = "DANGXULY";

        public ResulTiepNhanHoSoModel EventVOneTiepNhan(TiepNhanHoSoModel model){
            try{
                ProfileEN profile = new ProfileEN();
                ProfileCompositionProfileListEN profileCompositionProfile = new ProfileCompositionProfileListEN();
                WorkflowProfileEN workflowProfile = new WorkflowProfileEN();
                ProfileService profileService = new ProfileService();
                ProfileCompositionProfileListService profileCompositionProfileListService = new ProfileCompositionProfileListService();
                WorkflowProfileService workflowProfileService = new WorkflowProfileService();
                ProfileStatusService profileStatusService = new ProfileStatusService();
                NodeWorkflowService nodeWorkflowService = new NodeWorkflowService();

                

                /*Step 1: Kiểm tra dữ liệu đầu vào*/
                ResulTiepNhanHoSoModel resulTest = Validation(model);
                if (resulTest.status == 0){
                    return resulTest;
                }
                /*Step2: Kiểm tra fill giá trị vào profile*/
                if (!this.FillDataIntoProfile(profile, model)){
                    return new ResulTiepNhanHoSoModel(){
                        status = 0,
                        message = string.Format("Eror 3: {0}", "File data Into Profile")
                    };
                }

                //Note: Nhờ anh Thái giúp em, Quy trình Vone; Tiếp nhận[anh mở /**/ build ok*/ 
                #region Note: Nhờ anh thái giúp em
                
                using (TransactionScope scope = new TransactionScope()){
                    this.NewProfileAction(profile, profileService, profileCompositionProfile, profileCompositionProfileListService, workflowProfile, nodeWorkflowService, workflowProfileService, model);
                    IList<NodeWorkflowEN> list = nodeWorkflowService.GetNodeWorkflowByWorkflow_Node(workflowProfile.WorkflowId, workflowProfile.NodeId);

                    profile = profileService.GetProfileById(this.profileId);
                    var nodeWfProfileTypeProgressService = new NodeWFProfileTypeProgressService();

                    var nodeWorkflowRollService = new NodeWorkflowRollService();
                    if (list.Count > 0){
                        var lst = nodeWorkflowRollService.GetNodeWorkflowRollByNodeWorkflow_ToCc(list[0].NodeWorkflowId, true, profile.ProfileTypeId);
                        if (lst.Count > 0){
                            NodeWorkflowEN nodeWorkflow = list[0];
                            if (nodeWorkflow != null)
                            {
                                var wp = new WorkflowProfileEN();
                                var profileApprove = new ProfileApproveEN();
                                var progressWorkService = new ProgressWorkService();

                                var currentProfileTypeProgressId = this.GetCurrentProfileTypeProgressId(nodeWorkflow, nodeWfProfileTypeProgressService, profile);

                                var nextProfileTypeProgressId = this.GetNextProfileTypeProgressId(nodeWorkflow, nodeWfProfileTypeProgressService, profile);

                                IList<CoordinationEN> coordinations = new List<CoordinationEN>();
                              
                                 this.InsertDBTransaction(nodeWorkflow,  profile, workflowProfileService,  profileService,     currentProfileTypeProgressId,   nextProfileTypeProgressId, progressWorkService,    wp,  coordinations,    profileApprove, model);
                                

                                ////Gứi mail, sms cho công dân đăng ký trong hồ sơ
                                //if (nodeWorkflow.Send == "EMAIL_SMS" || nodeWorkflow.Send == "EMAIL")
                                //{
                                //    this.EmailCongDan(profile);
                                //}
                                //else if (nodeWorkflow.Send == "EMAIL_SMS" || nodeWorkflow.Send == "SMS")
                                //{
                                //    this.SmsCongDan(profile);
                                //}

                                 if (model.Email != null) {
                                    this.EmailCongDan(profile);
                                 }
                                 if (model.SmsGet != null) {
                                    this.SmsCongDan(profile);
                                 }

                                ////Gửi mail/Sms cho người nhận
                                this.EmailSmsNguoiNhan(profile, workflowProfile, profileApprove, coordinations, nodeWorkflow);
                            }

                        }
                    }

                    scope.Complete();
                }
                
                #endregion

                return new ResulTiepNhanHoSoModel() {
                    status = 1,
                    message = string.Format("Tiếp nhận thành công! Mã hồ sơ cuả khách hàng là {0}", profile.Code)
                };
            }
            catch (Exception ex)
            {
                return new ResulTiepNhanHoSoModel()
                {
                    status = 0,
                    message = ex.Message
                };
            }
        }

        /// <summary>
        /// The insert db transaction.
        /// </summary>
        /// <param name="nodeWorkflow">
        /// The node workflow.
        /// </param>
        /// <param name="profile">
        /// The profile.
        /// </param>
        /// <param name="workflowProfileService">
        /// The workflow profile service.
        /// </param>
        /// <param name="profileService">
        /// The profile service.
        /// </param>
        /// <param name="currentProfileTypeProgressId">
        /// The current profile type progress id.
        /// </param>
        /// <param name="nextProfileTypeProgressId">
        /// The next profile type progress id.
        /// </param>
        /// <param name="progressWorkService">
        /// The progress work service.
        /// </param>
        /// <param name="wp">
        /// The wp.
        /// </param>
        /// <param name="coordinations">
        /// The coordinations.
        /// </param>
        /// <param name="profileApprove">
        /// The profile approve.
        /// </param>
        private void InsertDBTransaction(NodeWorkflowEN nodeWorkflow, ProfileEN profile,   WorkflowProfileService workflowProfileService,  ProfileService profileService, int currentProfileTypeProgressId,
            int nextProfileTypeProgressId,
            ProgressWorkService progressWorkService,
            WorkflowProfileEN wp,
            IList<CoordinationEN> coordinations,
            ProfileApproveEN profileApprove, TiepNhanHoSoModel model) {
            int progressWorkId;

            using (var scope = new TransactionScope()) {
                if (currentProfileTypeProgressId != nextProfileTypeProgressId) {
                    progressWorkId = this.CurrentIdDiffNextId(currentProfileTypeProgressId, nextProfileTypeProgressId, progressWorkService);
                }
                else {
                    progressWorkId = workflowProfileService.GetWorkflowProfileByCurrent_Profile(true, this.profileId).ProgressWorkId;
                }

                if (nodeWorkflow.ProfileStatus.Code == Constants.ProfileStatus.KETTHUC) {
                    ProgressWorkEN progressW = progressWorkService.GetProgressWorkById(progressWorkId);
                    progressW.FinishDate = DateTime.Now;
                    progressW.Status = Hoanthanh;
                    progressWorkService.Update(progressW);
                }

                int workflowProfileId;

                this.UpdateFinishWorkflowProfile(workflowProfileService);

                ////Insert thông tin workflowprofile vào bảng WorkflowProfile
                var user = this.InsertNewWorkflowProfile(nodeWorkflow, workflowProfileService, wp, progressWorkId, out workflowProfileId, model);

                ////Insert người nhận Cc vào bảng Coordination
                this.InsertCc(profile, nodeWorkflow, wp, coordinations, workflowProfileId);

                ////Update trang thai moi cho Profile
                profile.ProfileStatusId = nodeWorkflow.ProfileStatusId;
                profileService.Update(profile);

                ////Insert thông tin vào bảng ProfileApprove
                this.InsertProfileApprove(nodeWorkflow, profileApprove, user);

                scope.Complete();
            }
        }

        /// <summary>
        /// The insert profile approve.
        /// </summary>
        /// <param name="nodeWorkflow">The node workflow.</param>
        /// <param name="profileApprove">The profile approve.</param>
        /// <param name="user">The user.</param>
        private void InsertProfileApprove(NodeWorkflowEN nodeWorkflow, ProfileApproveEN profileApprove, int user) {
            var profileApproveService = new ProfileApproveService();
            profileApprove.ProfileId = this.profileId;
            profileApprove.UserId = user;
            profileApprove.ApproveDate = DateTime.Now;
            profileApprove.ProfileStatusId = nodeWorkflow.ProfileStatusId;

            /*Chua biet thong so gi*/
            //profileApprove.DepartmentId = Convert.ToInt32(this.Session[Constants.SessionKey.CurrentDepartmentId]);
            UserDepartmentEN useren = new UserDepartmentService().GetDefaultUserDepartment(user);
            profileApprove.DepartmentId = useren.DepartmentId;

            profileApprove.ProfileStatusDisplay = nodeWorkflow.NextNode.Name;
            profileApproveService.Insert(profileApprove);
        }

        /// <summary>
        /// The insert cc.
        /// </summary>
        /// <param name="wp">
        /// The wp.
        /// </param>
        /// <param name="coordinations">
        /// The coordinations.
        /// </param>
        /// <param name="workflowProfileId">
        /// The workflow profile id.
        /// </param>
        private void InsertCc(ProfileEN profile, NodeWorkflowEN nodeWorkflow, WorkflowProfileEN wp, IList<CoordinationEN> coordinations, int workflowProfileId) {
            
            var nodeWorkflowRollService = new NodeWorkflowRollService();
            var userService = new UserService();
            var userRoles = new List<UserRole>();

            foreach (NodeWorkflowRollEN nodeWorkflowRoll in
                nodeWorkflowRollService.GetNodeWorkflowRollByNodeWorkflow_ToCc(nodeWorkflow.NodeWorkflowId, false, profile.ProfileTypeId)) {
                var lst = userService.GetUserRoleByDepartmentAndRollName(nodeWorkflowRoll.DepartmentId, nodeWorkflowRoll.RoleName);
                userRoles.AddRange(lst);
            }

            IList<NguoiNhan> list = new List<NguoiNhan>();

            foreach (UserRole userRole in userRoles) {
                MembershipProvider membershipProvider = Membership.Providers[Aspnetsqlmembershipprovider];
                if (membershipProvider != null) {
                    var membershipUser = membershipProvider.GetUser(userRole.UserDepartment.User.UserName, false);
                    if (membershipUser != null) {
                        if (membershipUser.IsApproved) {
                            list.Add(
                                userRole.ConvertToNguoiNhan(
                                    this.SetDefaultUser(false, userRole.UserDepartment.UserId, nodeWorkflow.NodeWorkflowId, profile.ProfileTypeId), false));
                        }
                    }
                }
            }

            var coordinationService = new CoordinationService();
            var userDepartmentService = new UserDepartmentService();

            foreach (var nguoiNhan in list) {
                int uId = userDepartmentService.GetUserDepartmentById(nguoiNhan.NguoiNhanId).UserId;

                if (uId != wp.MainUserId) {
                    var coordination = new CoordinationEN();
                    coordination.WorkflowProfileId = workflowProfileId;
                    coordination.CoordinationUserId = uId;
                    coordination.Role = nguoiNhan.Role;
                    coordination.RW = nguoiNhan.Rw;

                    coordinationService.Insert(coordination);
                    coordinations.Add(coordination);
                }
            }
        }

        /// <summary>
        /// The insert new workflow profile.
        /// </summary>
        /// <param name="nodeWorkflow">
        /// The node workflow.
        /// </param>
        /// <param name="workflowProfileService">
        /// The workflow profile service.
        /// </param>
        /// <param name="wp">
        /// The wp.
        /// </param>
        /// <param name="progressWorkId">
        /// The progress work id.
        /// </param>
        /// <param name="workflowProfileId">
        /// The workflow profile id.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        private int InsertNewWorkflowProfile(
            NodeWorkflowEN nodeWorkflow,
            WorkflowProfileService workflowProfileService,
            WorkflowProfileEN wp,
            int progressWorkId,
            out int workflowProfileId, TiepNhanHoSoModel model) {
           

            wp.ProfileId = this.profileId;
            wp.WorkflowId = nodeWorkflow.WorkflowId;
            wp.NodeId = nodeWorkflow.NextNodeId;

            int user = 0;
            user = model.UserId; //Convert.ToInt32(this.Session[Constants.SessionKey.CurrentUserId]);

            wp.SendUserId = user;
            /*chưa biết gia trị gì*/
            //wp.SendDepartmentId = Convert.ToInt32(this.Session[Constants.SessionKey.CurrentDepartmentId]);    
            /*đã fix*/
            UserDepartmentEN useren = new UserDepartmentService().GetDefaultUserDepartment(user);
            wp.SendDepartmentId = useren.DepartmentId;

            var profileService = new ProfileService();
            var profile = profileService.GetProfileById(this.profileId);

            var nodeWorkflowRollService = new NodeWorkflowRollService();
            var lst = nodeWorkflowRollService.GetNodeWorkflowRollByNodeWorkflow_ToCc(nodeWorkflow.NodeWorkflowId, true,
                                                                           profile.ProfileTypeId);

            int mainUser = 0;

            foreach (NodeWFRoleDefaultEN nodeWfRoleDefault in lst[0].NodeWfRoleDefaults) {
                if (nodeWfRoleDefault.ProfileTypeId == profile.ProfileTypeId) {
                    mainUser = nodeWfRoleDefault.UserDefaults[0].UserId;
                }
            }

            wp.MainUserId = mainUser;

            wp.MainDepartmentId = lst[0].DepartmentId;

            wp.ProgressWorkId = progressWorkId;
            wp.IsCurrent = true;
            wp.StartDate = DateTime.Now;
            if (nodeWorkflow.ProfileStatus.Code == Constants.ProfileStatus.KETTHUC) {
                wp.EndDate = DateTime.Now;
            }
            else {
                wp.EndDate = null;
            }

            wp.Role = "Xử lý chính";
            wp.RW = true;

            workflowProfileId = workflowProfileService.Insert(wp);

           

            return user;
        }

        /// <summary>
        /// The update finish workflow profile.
        /// </summary>
        /// <param name="workflowProfileService">
        /// The workflow profile service.
        /// </param>
        private void UpdateFinishWorkflowProfile(WorkflowProfileService workflowProfileService) {
            WorkflowProfileEN workflowProfile;
            workflowProfile = workflowProfileService.GetWorkflowProfileByCurrent_Profile(true, this.profileId);
            workflowProfile.IsCurrent = false;
            workflowProfile.EndDate = DateTime.Now;
            workflowProfileService.Update(workflowProfile);
        }

        /// <summary>
        /// The current id diff next id.
        /// </summary>
        /// <param name="currentProfileTypeProgressId">
        /// The current profile type progress id.
        /// </param>
        /// <param name="nextProfileTypeProgressId">
        /// The next profile type progress id.
        /// </param>
        /// <param name="progressWorkService">
        /// The progress work service.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        private int CurrentIdDiffNextId(
            int currentProfileTypeProgressId, int nextProfileTypeProgressId, ProgressWorkService progressWorkService) {
            ProgressWorkEN progressWork;
            int progressWorkId;
            progressWork = progressWorkService.GetProgressWorkByProfileTypeProgress_Profile(
                currentProfileTypeProgressId, this.profileId);

            if (progressWork != null) {
                progressWork.FinishDate = DateTime.Now;
                progressWork.Status = Hoanthanh;
                progressWorkService.Update(progressWork);
            }

            ProgressWorkEN prow =
                progressWorkService.GetProgressWorkByProfileTypeProgress_Profile(
                    nextProfileTypeProgressId, this.profileId);

            if (prow != null) {
                prow.FinishDate = null;
                prow.Status = Dangxuly;
                progressWorkService.Update(prow);
                progressWorkId = prow.ProgressWorkId;
            }
            else {
                var progress = new ProgressWorkEN();
                progress.ProfileTypeProgressId = nextProfileTypeProgressId;
                progress.ProfileId = this.profileId;
                progress.StartDate = DateTime.Now;
                progress.Status = Dangxuly;
                progressWorkId = progressWorkService.Insert(progress);
            }

            return progressWorkId;
        }

        /// <summary>
        /// Emails the cong dan.
        /// </summary>
        /// <param name="profile">The profile.</param>
        private void EmailCongDan(ProfileEN profile)
        {
            var emailSmsTemplateService = new EmailSmsTemplateService();

            var emailSmsTemplate = emailSmsTemplateService.GetEmailSmsTemplateGetByCode(Constants.Emailsmstemp.Tths);

            string body = PublicFuncs.GetFormattedTempalteEmail(
                Constants.Emailsmstemp.Tths,
                emailSmsTemplate.Email,
                tenCongDan: profile.OrganName,
                maHoSo: profile.Code,
                tenHoSo: profile.Name,
                trangThai: profile.ProfileStatus.Name,
                ngayTiepNhan: profile.ReceivingDate.Value.ToString(Constants.DateTimeDisplay),
                ngayHenTra: profile.AppointmentDate.Value.ToString(Constants.DateTimeDisplay));

            if (profile.Email != string.Empty){
            /*Note: đã fix*/
            SendEmail.SendMail(
                profile.Email,
                PublicFuncs.GetAppSettings(Constants.EmailSmsConfig.SystemMail),
                string.Empty,
                Constants.EmailSmsConfig.ThongTinHoSoSubject,
                body
                );
            }
        }
        /// <summary>
        /// SMSs the cong dan.
        /// </summary>
        /// <param name="profile">The profile.</param>
        private void SmsCongDan(ProfileEN profile)
        {
            var emailSmsTemplateService = new EmailSmsTemplateService();

            var emailSmsTemplate = emailSmsTemplateService.GetEmailSmsTemplateGetByCode(Constants.Emailsmstemp.Tths);

            if (profile.SmsGet != string.Empty)
            {
                string bodySms = PublicFuncs.GetFormattedTempalteSms(
                    Constants.Emailsmstemp.Tths,
                    emailSmsTemplate.Sms,
                    maHoSo: profile.Code,
                    trangThai: PublicFuncs.ConvertStringToUnsign(profile.ProfileStatus.Name),
                    ngayHenTra: profile.AppointmentDate.Value.ToString(Constants.DateTimeDisplay));

                this.SendSms(bodySms, profile.SmsGet);
            }
        }

        /// <summary>
        /// Sends the SMS.
        /// </summary>
        /// <param name="bodySms">
        /// The body SMS.
        /// </param>
        /// <param name="phone">
        /// The phone.
        /// </param>
        private void SendSms(string bodySms, string phone){
            string methodName = MethodBase.GetCurrentMethod().DeclaringType + Constants.Dot   + MethodBase.GetCurrentMethod().Name;
            LogHelper.Instance.WriteInfo(Constants.Begin + methodName);

            long mtseq = PublicFuncs.SMS_GetMaxMTSEQ();
            mtseq++; ////3 - 50

            string phoneNumber = PublicFuncs.GetValidMobileNumber(phone);
            if (!string.IsNullOrEmpty(phoneNumber))
            {
                if (bodySms.Length <= 160)
                {
                    var ws = new VDC.VONE.WSERIVCE.SMSAgentWSSoapClient.SMSAgentWS();
                    int status = 10000;
                    try
                    {
                        LogHelper.Instance.WriteInfo("Begin call WS send SMS to " + phoneNumber);

                        status = ws.SendMT(
                            mtseq.ToString(CultureInfo.CurrentCulture),
                            Constants.EmailSmsConfig.Number169,
                            Constants.EmailSmsConfig.Number169,
                            Constants.EmailSmsConfig.Number8788,
                            phoneNumber,
                            Constants.EmailSmsConfig.CodeSms,
                            bodySms,
                            Constants.EmailSmsConfig.TypeSms,
                            string.Empty,
                            Constants.EmailSmsConfig.Number1,
                            Constants.EmailSmsConfig.Number1,
                            Constants.EmailSmsConfig.Number169,
                            DateTime.Now.ToString(Constants.LongDateTimeDisplay),
                            Constants.EmailSmsConfig.Number0,
                            Constants.EmailSmsConfig.OpId,
                            Constants.EmailSmsConfig.UserWs,
                            Constants.EmailSmsConfig.PassWs);

                        LogHelper.Instance.WriteInfo("End call WS send SMS to " + phoneNumber);
                        LogHelper.Instance.WriteInfo("Send sms Success.");
                    }
                    catch (Exception exception)
                    {
                        status = 10000;
                        LogHelper.Instance.WriteError(methodName + Constants.Colon + exception.Message);
                    }
                    finally
                    {
                        PublicFuncs.InsertDBSendSMS(
                            mtseq, phoneNumber, bodySms, Constants.EmailSmsConfig.CxlModuleSms, status);
                    }
                }

            }

            LogHelper.Instance.WriteLog(HttpContext.Current.User.Identity.Name, methodName, false);
            LogHelper.Instance.WriteInfo(Constants.End + methodName);
        }

        /// <summary>
        /// Emails the SMS nguoi nhan.
        /// </summary>
        private void EmailSmsNguoiNhan(ProfileEN profile,
            WorkflowProfileEN wp,
            ProfileApproveEN profileApprove,
            IList<CoordinationEN> coordinations,
            NodeWorkflowEN nodeWorkflow)
        {
            EmailSmsTemplateEN emailSmsTemplate;
            EmailSmsTemplateService emailSmsTemplateService = new EmailSmsTemplateService();
            string bodyNguoiNhan = string.Empty;
            /*Note: Không biết cách giãi quyết ở đây là gi*/
            //string link = this.Request.Url.Scheme + Splash + this.Request.Url.Authority  + GiaiquyetthutuchanhchinheditAspx + this.Request.Url.Query;
            string link = "";

            emailSmsTemplate = emailSmsTemplateService.GetEmailSmsTemplateGetByCode(Constants.Emailsmstemp.Tthc);
            if (wp.MainUser != null && wp.SendUser != null)
            {
                if (profile.ReceivingDate != null)
                {
                    if (profile.AppointmentDate != null)
                    {
                        bodyNguoiNhan = PublicFuncs.GetFormattedTempalteEmail(
                            Constants.Emailsmstemp.Tthc,
                            emailSmsTemplate.Email,
                            nguoiNhan: wp.MainUser.FullName,
                            nguoiGui: wp.SendUser.FullName,
                            maHoSo: profile.Code,
                            tenHoSo: profile.Name,
                            loaiHoSo: profile.ProfileType.Name,
                            trangThai: profile.ProfileStatus.Name,
                            ngayTiepNhan: profile.ReceivingDate.Value.ToString(Constants.DateTimeDisplay),
                            ngayHenTra: profile.AppointmentDate.Value.ToString(Constants.DateTimeDisplay),
                            vaiTro: wp.Role,
                            lyDo: profileApprove.Reason.Replace("\n", "<br/>"),
                            link: link);
                    }
                }

                if (wp.MainUser.Send == Constants.EmailSmsConfig.Sms
                    || wp.MainUser.Send == Constants.EmailSmsConfig.EmailSms)
                {
                    string bodySms = PublicFuncs.GetFormattedTempalteSms(
                        Constants.Emailsmstemp.Tthc,
                        emailSmsTemplate.Sms,
                        nguoiGui: wp.SendUser.FullName,
                        maHoSo: profile.Code,
                        trangThai: PublicFuncs.ConvertStringToUnsign(profile.ProfileStatus.Name),
                        link: link);

                    this.SendSms(bodySms, wp.MainUser.Sms);
                }
            }

            if (bodyNguoiNhan != string.Empty)
            {
                var listAddCC = this.GetListCc(profile, nodeWorkflow, coordinations);

                string f = PublicFuncs.GetAppSettings(Constants.EmailSmsConfig.SystemMail);

                if (wp.SendUser != null && wp.SendUser.Email != string.Empty)
                {
                    f = wp.SendUser.Email;
                }

                if (wp.MainUser != null
                    && (wp.MainUser.Send == Constants.EmailSmsConfig.Email
                        || wp.MainUser.Send == Constants.EmailSmsConfig.EmailSms)){
                        /*Note: đã fix by luulong*/
                        SendEmail.SendMail(
                            wp.MainUser.Email,
                            f,
                            listAddCC,
                            Constants.EmailSmsConfig.ThuTucHanhChinhSubject,
                            bodyNguoiNhan
                            );
                }
                else
                {
                    if (!string.IsNullOrEmpty(listAddCC))
                    {
                    /*Note: Đã fix by luulong*/
                    SendEmail.SendMail(
                            PublicFuncs.GetAppSettings(Constants.EmailSmsConfig.SystemMail),
                            f,
                            listAddCC,
                            Constants.EmailSmsConfig.ThuTucHanhChinhSubject,
                            bodyNguoiNhan
                        );
                    }
                }
            }
        }

        /// <summary>
        /// The get list cc.
        /// </summary>
        /// <param name="coordinations">
        /// The coordinations.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        private string GetListCc(ProfileEN profile, NodeWorkflowEN nodeWorkflow, IList<CoordinationEN> coordinations)
        {
            string listAddCC = string.Empty;
            IList<string> coordinationEmail = new List<string>();
            var nodeWorkflowRollService = new NodeWorkflowRollService();

            var userRoles = new List<UserRole>();
            var userService = new UserService();

            foreach (NodeWorkflowRollEN nodeWorkflowRoll in
                nodeWorkflowRollService.GetNodeWorkflowRollByNodeWorkflow_ToCc(nodeWorkflow.NodeWorkflowId, false, profile.ProfileTypeId))
            {
                var lst = userService.GetUserRoleByDepartmentAndRollName(nodeWorkflowRoll.DepartmentId, nodeWorkflowRoll.RoleName);
                userRoles.AddRange(lst);
            }

            IList<NguoiNhan> list = new List<NguoiNhan>();

            foreach (UserRole userRole in userRoles)
            {
                MembershipProvider membershipProvider = Membership.Providers[Aspnetsqlmembershipprovider];
                if (membershipProvider != null)
                {
                    var membershipUser = membershipProvider.GetUser(userRole.UserDepartment.User.UserName, false);
                    if (membershipUser != null)
                    {
                        if (membershipUser.IsApproved)
                        {
                            list.Add(
                                userRole.ConvertToNguoiNhan(this.SetDefaultUser(false, userRole.UserDepartment.UserId, nodeWorkflow.NodeWorkflowId, profile.ProfileTypeId), false));
                        }
                    }
                }
            }

            if (list.Count > 0)
            {
                UserDepartmentEN userDepartment = new UserDepartmentEN();
                UserDepartmentService userDepartmentService = new UserDepartmentService();

                foreach (var nn in list)
                {
                    userDepartment = userDepartmentService.GetUserDepartmentById(nn.NguoiNhanId);
                    if (userDepartment.User.Send == Constants.EmailSmsConfig.Email
                        || userDepartment.User.Send == Constants.EmailSmsConfig.EmailSms)
                    {
                        coordinationEmail.Add(userDepartment.User.Email);
                    }
                }

                listAddCC = string.Join(Separator, coordinationEmail);

            }

            return listAddCC;
        }

        /// <summary>
        /// Sets the default user.
        /// </summary>
        /// <param name="toCc">if set to <c>true</c> [to cc].</param>
        /// <param name="userId">The user id.</param>
        /// <param name="nodeWorkflowId">The node workflow id.</param>
        /// <param name="profileTypeId">The profile type id.</param>
        /// <returns>
        /// return bool
        /// </returns>
        private bool SetDefaultUser(bool toCc, int userId, int nodeWorkflowId, int profileTypeId)
        {
            int userIdDefault = -1;

            var lst = new List<UserDefaultEN>();
            var userDeault = new UserDefaultEN();
            var userDefaultService = new UserDefaultService();
            lst = userDefaultService.GetUserDefaultByNodeWorkflow_ToCc_ProfileType(nodeWorkflowId, toCc, profileTypeId);

            if (lst.Count > 0)
            {
                if (toCc)
                {
                    if (userDeault != lst[0])
                    {
                        userIdDefault = userDeault.UserId;
                    }

                    if (userId == userIdDefault)
                    {
                        return true;
                    }
                }
                else
                {
                    foreach (var userDefaultEn in lst)
                    {
                        if (userDefaultEn.UserId == userId)
                        {
                            return true;
                        }
                    }
                }
            }

            return false;
        }


        private ResulTiepNhanHoSoModel Validation(TiepNhanHoSoModel model)
        {
            try
            {
                /*B1:Kiểm tra loại thủ tục*/
                ProfileTypeEN profile = (new ProfileTypeData()).GetProfileTypeById(model.ProfileTypeId);
                if (profile == null)
                    return new ResulTiepNhanHoSoModel() { status = 0, message = string.Format("Error 10: {0}", "Thủ tục không tồn tại trong hệ thống Vone.") };

                /*B2: Kiểm tra thành phần hồ sơ theo ID thủ tục*/
                if (model.CompositionProfileListIds.Count() != 0)
                {/*Nếu có tồn tại thành phần hồ sơ thì kt thành phần hỗ sơ có đúng với thành phần hồ sơ cuà dữ liệu theo id thủ tục không, tránh trường hợp cline đưa nhầm*/
                    List<CompositionProfileList> compositionList = (from a in (new CompositionProfileListData().GetCompositionProfileLists())
                                                                    join b in (new ProfileTypeCompositionProfileListData().GetProfileTypeCompositionProfileLists()) on a.CompositionProfileListId equals b.CompositionProfileListId
                                                                    where b.ProfileTypeId == model.ProfileTypeId
                                                                    select new CompositionProfileList
                                                                    {
                                                                        CompositionProfileListId = a.CompositionProfileListId,
                                                                        Name = a.Name,
                                                                        Code = a.Code
                                                                    }).ToList();
                    bool temp = true;
                    foreach (var item in model.CompositionProfileListIds){
                        if (compositionList.Where(p=>p.CompositionProfileListId == Convert.ToInt32(item)).Count()==0){
                            temp = false;
                            break;
                        }
                    }
                    if (!temp)
                        return new ResulTiepNhanHoSoModel() { status = 0, message = string.Format("Error 11: {0}", "Thành phần hồ sơ không khớp theo ID thủ tục.") };
                }
                /*B3: Nếu không có tên hồ sơ thì báo lổi*/
                if (model.Name == null || model.Name.Trim() == "")
                    return new ResulTiepNhanHoSoModel() { status = 0, message = string.Format("Error 12: {0}", "Tên hồ sơ không được rỗng.") };
                /*B4: Kiểm tra Level*/
                List<Level> levels = (from a in (new LevelData()).GetLevels()
                                      select new Level()
                                      {
                                          LevelId = a.LevelId,
                                          Name = a.Name,
                                      }).ToList();

                if (levels.Where(p => p.LevelId == model.LevelId).Count() == 0) {
                    return new ResulTiepNhanHoSoModel() {
                        status = 0,
                        message = string.Format("Error 14: {0}", "Trạng thái cấp đối tượng thực hiện không tồn tại trong VOne")
                    };
                }


                /*B5: Kiểm tra Tên tổ chức/ cá nhân*/
                if (model.OrganName ==null || model.OrganName.Trim() == "")
                    return new ResulTiepNhanHoSoModel() { status = 0, message = string.Format("Error 15: {0}", "Tên tổ chứ không được rỗng.") };

                /*B6: Kiễm tra file đính kèm Attachments, nếu kh có gữi file theo*/
                if (model.Attachments != null && model.Attachments.f != null)
                {
                    string strNameNew = "";
                    if (UploadFile(model.Attachments.f, model.Attachments.fileName, ref strNameNew))
                        model.Attachments.fileName = strNameNew;/*Cập nhật lại tên file đã được đổi theo Guid.NewGuid()*/
                    else
                        return new ResulTiepNhanHoSoModel() {
                        status = 0,
                        message = string.Format("Error 16: {0}", "Đơn đính kèm! Không lưu được file nội dung đơn")
                        };
                }

                /*B7: Kiễm tra file đính kèm AttachmentsOriginal, nếu khách hàng có gữi file theo*/
                if (model.AttachmentsOriginal!=null && model.AttachmentsOriginal.f != null)             {
                    string strNameNew = "";
                    if (UploadFile(model.AttachmentsOriginal.f, model.AttachmentsOriginal.fileName, ref strNameNew))
                        model.AttachmentsOriginal.fileName = strNameNew;/*Cập nhật lại tên file đã được đổi theo Guid.NewGuid()*/
                    else
                        return new ResulTiepNhanHoSoModel() {
                        status = 0,
                        message = string.Format("Error 17: {0}", "Hồ sơ gốc! Không lưu được hồ sơ gốc")
                        };
                }
                /*===========================Kết thúc kiểm tra================================*/
                return new ResulTiepNhanHoSoModel() { status = 1, message = string.Format("Success: {0}", "Kiểm tra thành công.") };
            }
            catch (Exception ex)
            {
                return new ResulTiepNhanHoSoModel()
                {
                    status = 0,
                    message = string.Format("Error 2: {0}", ex.Message)
                };
            }
        }

        /// <summary>
        /// The new profile action.
        /// </summary>
        /// <param name="profile">
        /// The profile.
        /// </param>
        /// <param name="profileService">
        /// The profile service.
        /// </param>
        /// <param name="profileCompositionProfile">
        /// The profile composition profile.
        /// </param>
        /// <param name="profileCompositionProfileListService">
        /// The profile composition profile list service.
        /// </param>
        /// <param name="workflowProfile">
        /// The workflow profile.
        /// </param>
        /// <param name="nodeWorkflowService">
        /// The node workflow service.
        /// </param>
        /// <param name="workflowProfileService">
        /// The workflow profile service.
        /// </param>
        private void NewProfileAction(ProfileEN profile,ProfileService profileService, ProfileCompositionProfileListEN profileCompositionProfile,  ProfileCompositionProfileListService profileCompositionProfileListService,
            WorkflowProfileEN workflowProfile,NodeWorkflowService nodeWorkflowService, WorkflowProfileService workflowProfileService,  TiepNhanHoSoModel model) {
            /*step 1: Insert Project*/
            profileId = profileService.Insert(profile);

            /*Step 2: Insert profileCompositionProfileList*/
            foreach (var item in model.CompositionProfileListIds){
                profileCompositionProfile.CompositionProfileListId = Convert.ToInt32(item.ToString()); //Convert.ToInt32(listItem.Value);
                profileCompositionProfile.ProfileId = this.profileId;
                profileCompositionProfileListService.Insert(profileCompositionProfile);
            }

            /*Step 3: Insert workflowProfile*/
            workflowProfile.ProfileId = this.profileId;
            workflowProfile.WorkflowId = profile.ProfileType.WorkflowId;

            foreach (NodeWorkflowEN nodeWorkflow in nodeWorkflowService.GetNodeWorkflowByWorkflowId(workflowProfile.WorkflowId))
            {
                if (nodeWorkflow.Node.NodeType.Code == Constants.Nodetype.Start)
                {
                    workflowProfile.NodeId = nodeWorkflow.NodeId;
                }
            }

            workflowProfile.IsCurrent = true;
            workflowProfile.StartDate = DateTime.Now;
            workflowProfile.RW = true;
            workflowProfile.Role = MainProcess;

            /*Note: nhờ anh thái kiễm tra giá trị này*/
            workflowProfile.MainUserId = model.UserId;
            //if (this.userId != -1)
            //{
            //    workflowProfile.MainUserId = this.userId;
            //}
            //

            /*Note: nhờ anh thái kiễm tra giá trị này*/
            //workflowProfile.MainDepartmentId = Convert.ToInt32(this.Session[Constants.SessionKey.CurrentDepartmentId]);
            /*da fix*/
            UserDepartmentEN useren= new UserDepartmentService().GetDefaultUserDepartment(model.UserId);
            workflowProfile.MainDepartmentId = useren.DepartmentId;

            workflowProfileService.Insert(workflowProfile);

        }

        /// <summary>
        /// The get next profile type progress id.
        /// </summary>
        /// <param name="nodeWorkflow">
        /// The node workflow.
        /// </param>
        /// <param name="nodeWfProfileTypeProgressService">
        /// The node wf profile type progress service.
        /// </param>
        /// <param name="profile">
        /// The profile.
        /// </param>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        private int GetNextProfileTypeProgressId(
            NodeWorkflowEN nodeWorkflow,
            NodeWFProfileTypeProgressService nodeWfProfileTypeProgressService,
            ProfileEN profile)
        {
            NodeWFProfileTypeProgressEN nodeWfProfileTypeProgress =
                nodeWfProfileTypeProgressService.GetNodeWfDefaultBy_NodeWorkflowProfileTypeId(
                    nodeWorkflow.NodeWorkflowId, profile.ProfileTypeId);

            int nextProfileTypeProgressId = 0;
            if (nodeWfProfileTypeProgress != null)
            {
                nextProfileTypeProgressId = nodeWfProfileTypeProgress.ProfileTypeProgressId;
            }

            return nextProfileTypeProgressId;
        }
        /// <summary>
        /// Gets the current profile type progress id.
        /// </summary>
        /// <param name="nodeWorkflow">The node workflow.</param>
        /// <param name="nodeWfProfileTypeProgressService">The node wf profile type progress service.</param>
        /// <param name="profile">The profile.</param>
        /// <returns></returns>
        private int GetCurrentProfileTypeProgressId(
            NodeWorkflowEN nodeWorkflow,
            NodeWFProfileTypeProgressService nodeWfProfileTypeProgressService,
            ProfileEN profile)
        {
            int nwId = this.DeQuy(nodeWorkflow);
            int currentProfileTypeProgressId = 0;

            if (nwId != 0)
            {
                NodeWFProfileTypeProgressEN node =
                    nodeWfProfileTypeProgressService.GetNodeWfDefaultBy_NodeWorkflowProfileTypeId(
                        nwId, profile.ProfileTypeId);
                if (node != null)
                {
                    currentProfileTypeProgressId = node.ProfileTypeProgressId;
                }
            }
            else
            {
                currentProfileTypeProgressId = 0;
            }

            return currentProfileTypeProgressId;
        }

        /// <summary>
        /// Des the quy.
        /// </summary>
        /// <param name="nodeWorkflow">
        /// The node workflow.
        /// </param>
        /// <returns>
        /// return int
        /// </returns>
        private int DeQuy(NodeWorkflowEN nodeWorkflow)
        {
            var nodeWorkflowService = new NodeWorkflowService();
            NodeWorkflowEN prev = (from node in nodeWorkflowService.GetNodeWorkflowByNextNodeId(nodeWorkflow.NodeId)
                                   where node.WorkflowId == nodeWorkflow.WorkflowId
                                   select node).FirstOrDefault();

            if (prev != null)
            {
                if (prev.Node.NodeType.Code == Constants.Nodetype.Condition)
                {
                    this.DeQuy(prev);
                }

                return prev.NodeWorkflowId;
            }

            return 0;
        }


        /// <summary>
        /// Hàm upload file, chuyễn dữ liệu từ byte sang file
        /// </summary>
        /// <param name="f"></param>
        /// <param name="fileName"></param>
        /// <param name="fileRename">Kết quả tên file sau khi rename randum</param>
        /// <returns>True/False</returns>
        private bool UploadFile(byte[] f, string fileName, ref string strNameNew){
            try
            {
                string path = string.Empty;
                string strName = string.Empty;
                string thongbao = Path.Combine(new DirectoryInfo(HostingEnvironment.ApplicationPhysicalPath).Parent.Name, @"C:\BinhDuong\VDC_VONE\VDC.VONE.WEB\Attachments\HoSo\");
                //string thongbao = Path.Combine(new DirectoryInfo(HostingEnvironment.ApplicationPhysicalPath).Parent.Name, @"C:\BinhDuong\");
                do
                {/*kiễm tra xem file randum co ton tai trung ten trong thu muc chứa file chua*/
                    strName = Guid.NewGuid().ToString(NumberFormat) + Underline + fileName.Replace(Underline, Dashes);
                    path = thongbao + strName;
                } while (System.IO.File.Exists(thongbao));

                MemoryStream ms = new MemoryStream(f);
                FileStream fs = new FileStream(path, FileMode.Create);

                ms.WriteTo(fs);
                strNameNew = strName;


                ms.Close();
                fs.Close();
                fs.Dispose();
                return true;
            }
            catch (Exception ex){
                return false;
            }
        }


        private bool FillDataIntoProfile(ProfileEN profile,TiepNhanHoSoModel model){
            profile.ProfileTypeId = Convert.ToInt32(model.ProfileTypeId);
            profile.LevelId = Convert.ToInt32(model.LevelId);
            profile.ProfileStatusId = (new ProfileStatusService()).GetProfileStatusByCode(Constants.ProfileStatus.TIEPNHAN).ProfileStatusId;

            var storageLocationProfileListService = new StorageLocationProfileListService();
            profile.StorageLocationProfileListId = storageLocationProfileListService.GetStorageLocationProfileLists()[0].StorageLocationProfileListId;
            profile.CreateUserId = model.UserId;
            profile.Code = GenerateCode();
            profile.Name = string.Format("Hồ sơ trực tuyến {0}", model.Name);/*yeu de nhan biet ho so truc tuyen*/
            profile.SmsGet = model.SmsGet != null ? model.SmsGet.Trim() : model.SmsGet;
            profile.Email = model.Email != null ? model.Email.Trim(): model.Email;
            profile.CreateDate = DateTime.Now;
            profile.ReceivingDate = DateTime.Now;/*mặc định do tiếp nhận online Ngày tiếp nhập là ngày hệ thống*/
            profile.AppointmentDate = GetToDate((new ProfileTypeData()).GetProfileTypeById(model.ProfileTypeId).ResolveDays);
            profile.Object = model.Object;
            profile.Notes = model.Notes != null ?  model.Notes.Trim() : model.Notes;
            profile.OrganName = model.OrganName != null? model.OrganName.Trim(): model.OrganName;
            profile.Address = model.Address !=null ?  model.Address.Trim() : model.Address;
            profile.Phone = model.Phone!=null ?  model.Phone.Trim(): model.Phone;
            profile.Attachments = model.Attachments == null ? null : string.Format("{0}", Path.Combine(PublicFuncs.GetAppSettings(FileUploadPathHoso), model.Attachments.fileName));
            //profile.AttachmentsOriginal = model.AttachmentsOriginal == null ? null : string.Format("{0}", Path.Combine(PublicFuncs.GetAppSettings(FileUploadPathHoso), model.AttachmentsOriginal.fileName));
            profile.AttachmentsOriginal = model.AttachmentsOriginal == null ? null : string.Format("{0};", Path.Combine(PublicFuncs.GetAppSettings(FileUploadPathHoso), model.AttachmentsOriginal.fileName)); /*by long cai này phai thêm dấu ; đã trao doi voi a thai */
            profile.IsOpen = false;
            return true;
        }

        /// <summary>
        ///     Generates the code.
        /// </summary>
        /// <returns>return string code ho so</returns>
        private string GenerateCode()
        {
            string result = MaHoSoOne;
            ProfileService profileService = new ProfileService();
            ProfileEN profile = profileService.GetNewestProfile();
            if (profile != null)
            {
                do
                {
                    result = profile.Code;
                    string[] numbers = Regex.Split(result, NumberPattern);
                    int next = Convert.ToInt32(numbers[1]) + 1;
                    result = Mhs + next;
                }
                while ((profile = profileService.GetProfileByCodeId(result, -1)) != null);
            }

            return result.Trim();
        }

        /// <summary>
        /// Hàm tíhn ngày lễ
        /// </summary>
        /// <param name="ResolveDays"></param>
        /// <returns></returns>
        public DateTime GetToDate(int ResolveDays)
        {
            DateTime temp = DateTime.Now.AddDays(ResolveDays);
            int result = PublicFuncs.GetHolidaysBetween(DateTime.Now, temp);
            DateTime temp2 = temp.AddDays(result);

            int extraResult = PublicFuncs.GetHolidaysBetween(temp, temp2);

            DateTime final = temp2.AddDays(extraResult);

            int finalDays = PublicFuncs.GetHolidaysBetween(DateTime.Now, final);
            return temp.AddDays(finalDays);
            //return = temp.AddDays(finalDays).ToString(Constants.DateTimeDisplay);
        }
    }
}

